public with sharing class LeadConversionOptions 
{

    public LeadConversionOptions() {

    }


    public string getUserLang(){
     return UserInfo.getLanguage();
    }
    public LeadConversionOptions(ApexPages.StandardController controller) {

    }

    public string option{get;set;}
    

         
    public boolean isOppty{get;set;}
    
    public string getCustomleadID()
    {
        string customleadID=ApexPages.currentPage().getParameters().get('LeadID');    
        return customleadID;
    }
    public string getcustomAccountID()
    {
        string customAccountID=ApexPages.currentPage().getParameters().get('act_id');
        return customAccountID;
    }
    
    public List<SelectOption> getItems() {
        List<SelectOption> options = new List<SelectOption>();
        If(getUserLang()=='es_MX'){
            options.add(new SelectOption('option0','--ninguno--'));
            options.add(new SelectOption('option1','Si- Unir el prospecto a la cuenta'));
            options.add(new SelectOption('option2','No- Crear nueva cuenta'));
                        //options.add(new SelectOption('option3','3) This lead is not a match; create a new Opportunity.')); 
        }Else{
            options.add(new SelectOption('option0','--None--'));
            options.add(new SelectOption('option1','Yes- Merge Lead and Account'));
            options.add(new SelectOption('option2','No- Create New Account'));
        }

return options;
}
    
    
     public PageReference getSelected()
     {
        system.debug('########## line 52');
        ApexPages.Message accErr = new ApexPages.Message(ApexPages.Severity.INFO,'There was a problem in updating person account. Please contact System Administrator');
        ApexPages.Message oppErr = new ApexPages.Message(ApexPages.Severity.INFO,'There was a problem in creating an Opportunity. Please contact System Administrator');
        ApexPages.Message leadErr = new ApexPages.Message(ApexPages.Severity.INFO,'There was a problem while converting the Lead. Please contact System Administrator');
        
//        lead led=[SELECT City,Country,PostalCode,State,Personal_Email__c,Street FROM LEAD where id=:ApexPages.currentPage().getParameters().get('LeadID')limit 1];
  //      account act=[SELECT  id,LeadConversionInProgress__c,PersonMailingCity,Personal_Email__pc,PersonMailingCountry,PersonMailingPostalCode,PersonMailingState,PersonMailingStreet FROM ACCOUNT where id=:ApexPages.currentPage().getParameters().get('act_id') limit 1];

      //Address Manipulation
      lead led=[SELECT City,Country,PostalCode,State,Street FROM LEAD where id=:ApexPages.currentPage().getParameters().get('LeadID')limit 1];
      account act=[SELECT  id,LeadConversionInProgress__c,PersonMailingCity,PersonMailingCountry,PersonMailingPostalCode,PersonMailingState,PersonMailingStreet FROM ACCOUNT where id=:ApexPages.currentPage().getParameters().get('act_id') limit 1];        

            AccountUpdate(led,act,true,option);
        
        List <string> leadFields = getoDescribe('Lead');
        List <string> actFields = getoDescribe('account');
        // build dynamic lead select statement
        string soqlLeadFormationText ='Id, ' ;
        string soqlActFormationText ='Id, ' ;
        integer leadFieldCount =0;
        integer actFieldCount =0;
        for (String lfm: leadFields)
        {
             leadFieldCount ++;
             if(leadFieldCount >1){soqlLeadFormationText +=', ';}
             soqlLeadFormationText += lfm; 
        }
        string ldSOQL = 'SELECT '+soqlLeadFormationText +'  FROM lead WHERE Id = \''+ ApexPages.currentPage().getParameters().get('LeadID')+'\' LIMIT 1';        
        lead lead= Database.query(ldSOQL );
        integer i=0;
        
        //Declaration of variables to add Account fields into map
        Map<string, string> AccountFieldsMap = new Map<string, string> {};
        string removedActPerson;
        string removedActpc;
        string removedActc;
        string removedActUnderscore;
        string removedActMailing;
        //end declaration
        
        for(i=0;i<actFields.size();i++)
        {
            if(i >0){soqlActFormationText +=', ';}
             soqlActFormationText += actFields[i]; 
             
            //Parse Account field names and add to map to compare against Lead field names
            removedActPerson= actFields[i].toLowerCase().replace('person','');
            removedActpc= removedActPerson.replace('__pc','');
            removedActc= removedActpc.replace('__c','');
            removedActUnderscore= removedActc.replace('_','');
            AccountFieldsMap.put(removedActUnderscore,actFields[i]);
            //end parse
        }
        string actSOQL = 'SELECT ispersonaccount,'+soqlActFormationText +'  FROM account WHERE Id = \''+ ApexPages.currentPage().getParameters().get('act_id')+'\' LIMIT 1';        
        account account= Database.query(actSOQL );
        List<task>  tskToUpdate = new List<task>();
        List<event>  eventToUpdate = new List<event>();


         //Lead lead=[SELECT Priority_Note__c ,Age__c, AnnualRevenue, Anticipated_Start_Date__c, Birth_Date__c, CEL_Assigned__c, CEL_Assigned_Date__c, CEL_Assigned_Legacy__c, Campus__c, Campus_Text__c, City, College_credits_outside_US__c, Company, IsConverted, ConvertedAccountID__c, ConvertedAccountId, ConvertedContactId, ConvertedDate, ConvertedDate__c, ConvertedOpportunityId__c, ConvertedOpportunityId, Country, Country_of_Birth__c, Country_of_Birth_Text__c, Country_of_Residence__c, Country_of_Residence_Text__c, CreatedById, CreatedDate, Credit_Level__c, Data_Mapping_Status__c, Date_Appointment__c, IsDeleted, Description, DoNotCall, Do_Not_Text_Message__c, Document_Storage_URL__c, Duplicate_Account__c, Duplicate_Lead__c, Email, EmailBouncedDate, EmailBouncedReason, HasOptedOutOfEmail, NumberOfEmployees, Employer__c, External_ID_1__c, External_ID_2__c, Fax, FirstName, Foreign_Credit__c, Name, Gender__c, Generic_Phone__c, Highest_Level_of_Education__c, Home_Phone__c, IRN__c, Industry, IsConverted__c, LastActivityDate, LastModifiedById, LastModifiedDate, LastName, Lead_Assigned_Date__c, Id, Lead_ID__c, LeadSource, Lead_Source_2__c, Lead_Source_Detail__c, Lead_Source_Detail_2__c, Marketing_Email__c, Marketing_Phone__c, MasterRecordId, Middle_Name__c, Military_Base__c, Military_Branch__c, Military_End_Date__c, Military_Rank__c, Military_Start_Date__c, Military_Status__c, Military_TDY__c, MobilePhone, Mode__c, Mode_Text__c, Other_Email__c, Other_Email_2__c, Other_Email_2_Description__c, Other_Email_Description__c, Other_Phone__c, Other_Phone_2__c, Other_Phone_2_Description__c, Other_Phone_Description__c, OwnerId, Personal_Email__c, Phone, Preferred_Email__c, Preferred_First_Name__c, Preferred_Phone__c, Previous_Last_Name__c, Primary_Payment_Option__c, Priority__c, Program__c, Program_Text__c, RecordTypeId, Salutation, Secondary_Payment_Option__c, State__c, State_Province__c, State, Status, Status_Detail__c, Street, SystemModstamp, Title, University_Email__c, IsUnreadByOwner, Website, Work_Email__c, Work_Phone__c, You_may_call_or_email_me__c, PostalCode, Date_Contacted__c, Date_Declined__c, Date_No_Further_Action__c FROM Lead where Id= :ApexPages.currentPage().getParameters().get('LeadID')];        
        //Account account=[SELECT  Priority_Note__pc,Employer_Text__pc,Description, Fax, Account_ID__c, Id, Name, Phone, Rating, Site, Type, Age__pc, AnnualRevenue, PersonAssistantName, PersonAssistantPhone, BillingCity, BillingCountry, BillingState, BillingStreet, BillingPostalCode, PersonBirthdate, CEL_Assigned__c, CEL_Assigned_Date__c, CEL_Assigned_Legacy__c, PersonContactId, Country_of_Birth__pc, Country_of_Residence__pc, CreatedById, CreatedDate, Credit_Level__pc, IsDeleted, PersonDepartment, PersonDoNotCall, Do_Not_Text_Message__pc, Document_Storage_URL__c, PersonEmail, PersonEmailBouncedDate, PersonEmailBouncedReason, PersonHasOptedOutOfEmail, NumberOfEmployees, Employer__pc, External_ID_1__c, External_ID_2__c, PersonHasOptedOutOfFax, FirstName, Foreign_Credit__pc, Gender__pc, PersonHomePhone, IRN__c, Industry, IsPersonAccount, LastActivityDate, LastModifiedById, LastModifiedDate, LastName, PersonLastCURequestDate, PersonLastCUUpdateDate, PersonLeadSource, Lead_Source_2__pc, Lead_Source_Detail__pc, PersonMailingCity, PersonMailingCountry, PersonMailingState, PersonMailingStreet, PersonMailingPostalCode, Marketing_Email__pc, Marketing_Phone__pc, MasterRecordId, Middle_Name__pc, Military_Base__pc, Military_Branch__pc, Military_End_Date__pc, Military_Rank__pc, Military_Start_Date__pc, Military_Status__pc, Military_TDY__pc, PersonMobilePhone, Opportunity_Applications_Accepted__c, Opportunity_Applications_in_Progress__c, PersonOtherCity, PersonOtherCountry, Other_Email__pc, Other_Email_2__pc, Other_Email_2_Description__pc, Other_Email_Description__pc, PersonOtherPhone, Other_Phone_2__pc, Other_Phone_2_Description__pc, Other_Phone_Description__pc, PersonOtherState, PersonOtherStreet, PersonOtherPostalCode, OwnerId, ParentId, Passport_Country_of_Issue__pc, Passport_Exp_Date__pc, Passport_Issue_Date__pc, Passport_Number__pc, Person_Account_Contact_ID__c, Personal_Email__pc, Personal_Information__pc, Preferred_Email__pc, Preferred_First_Name__pc, Preferred_Phone__pc, Previous_Last_Name__pc, Primary_Nationality__pc, RecordTypeId, Salutation, Secondary_Nationality__pc, ShippingCity, ShippingCountry, ShippingState, ShippingStreet, ShippingPostalCode, Status__c, SystemModstamp, PersonTitle, University_Email__pc, Website, Work_Email__pc, Work_Phone__pc, Lead_Source_Detail_2__pc, Opportunities_Alumni__c, Opportunities_Maintenance__c, Opportunities_No_Further_Action__c FROM Account where Id=:ApexPages.currentPage().getParameters().get('act_id')];
        //Account account=[SELECT Description, Fax, Account_ID__c, Id, Name, Phone, Rating, Site, Type, Age__pc, AnnualRevenue, PersonAssistantName, PersonAssistantPhone, BillingCity, BillingCountry, BillingState, BillingStreet, BillingPostalCode, PersonBirthdate, CEL_Assigned__c, CEL_Assigned_Date__c, CEL_Assigned_Legacy__c, PersonContactId, Country_of_Birth__pc, Country_of_Residence__pc, CreatedById, CreatedDate, Credit_Level__pc, IsDeleted, PersonDepartment, PersonDoNotCall, Do_Not_Text_Message__pc, Document_Storage_URL__c, PersonEmail, PersonEmailBouncedDate, PersonEmailBouncedReason, PersonHasOptedOutOfEmail, NumberOfEmployees, Employer__pc, External_ID_1__c, External_ID_2__c, PersonHasOptedOutOfFax, FirstName, Foreign_Credit__pc, Gender__pc, PersonHomePhone, IRN__c, Industry, IsPersonAccount, LastActivityDate, LastModifiedById, LastModifiedDate, LastName, PersonLastCURequestDate, PersonLastCUUpdateDate, PersonLeadSource, Lead_Source_2__pc, Lead_Source_Detail__pc, PersonMailingCity, PersonMailingCountry, PersonMailingState, PersonMailingStreet, PersonMailingPostalCode, Marketing_Email__pc, Marketing_Phone__pc, MasterRecordId, Middle_Name__pc, Military_Base__pc, Military_Branch__pc, Military_End_Date__pc, Military_Rank__pc, Military_Start_Date__pc, Military_Status__pc, Military_TDY__pc, PersonMobilePhone, Opportunity_Applications_Accepted__c, Opportunity_Applications_in_Progress__c, PersonOtherCity, PersonOtherCountry, Other_Email__pc, Other_Email_2__pc, Other_Email_2_Description__pc, Other_Email_Description__pc, PersonOtherPhone, Other_Phone_2__pc, Other_Phone_2_Description__pc, Other_Phone_Description__pc, PersonOtherState, PersonOtherStreet, PersonOtherPostalCode, OwnerId, ParentId, Passport_Country_of_Issue__pc, Passport_Exp_Date__pc, Passport_Issue_Date__pc, Passport_Number__pc, Person_Account_Contact_ID__c, Personal_Email__pc, Personal_Information__pc, Preferred_Email__pc, Preferred_First_Name__pc, Preferred_Phone__pc, Previous_Last_Name__pc, Primary_Nationality__pc, RecordTypeId, Salutation, Secondary_Nationality__pc, ShippingCity, ShippingCountry, ShippingState, ShippingStreet, ShippingPostalCode, Status__c, SystemModstamp, PersonTitle, University_Email__pc, Website, Work_Email__pc, Work_Phone__pc FROM Account where Id=:ApexPages.currentPage().getParameters().get('act_id')];       
        
        // build dynamic lead select statement
        // get a dynamic list of object fields for matching and converting        
        List <string> leadfieldMap = leadFields; 
        List <string> accountfieldMap = actFields ;              
        List <string> opptyfieldMap = getoDescribe('Opportunity');   
        
        //Declaration of variables to add Opportunity fields into map
        Map<string, string> OpptyFieldsMap = new Map<string, string> {};
        string removedOpptyc;
        string removedOpptyUnderscore;
        //end declaration
        
        //Parse Opportunity field names and add to map to compare against Lead field names
        for(i=0;i<opptyfieldMap.size();i++)
        {
             removedOpptyc= opptyfieldMap[i].toLowerCase().replace('__c','');
             removedOpptyUnderscore= removedOpptyc.replace('_','');
             OpptyFieldsMap.put(removedOpptyUnderscore,opptyfieldMap[i]);
        }
        //end parse 
            
        string removedLeadc;
        string removedLeadUnderscore;
        
        Map<string, string> LeadAccountMap = new Map<string, string> {};
        Map<string, string> LeadOpptyMap = new Map<string, string> {};
        integer cnt=0;
        List<string> newAccountList=new List<string>();
         for (cnt=0;cnt<leadfieldMap.size();cnt++) 
         {       
            removedLeadc='';
            removedLeadUnderscore='';            

            // default address is PersonMailing
            removedLeadc= leadfieldMap[cnt].toLowerCase().replace('__c','');            
            removedLeadUnderscore= removedLeadc.replace('_','');   
            
            //Compare Account fields with Lead fields; if match, add to Lead/Account map for later use
            if((AccountFieldsMap.containsKey(removedLeadUnderscore)) && (leadfieldMap[cnt]!='RecordTypeId') && (leadfieldMap[cnt] !='Name'))
                {           
                    LeadAccountMap.put(AccountFieldsMap.get(removedLeadUnderscore),leadfieldMap[cnt]);
                }
            //END compare
            
            //Compare Opportunity fields with Lead fields; if match, add to Lead/Opportunity map for later use
            if((OpptyFieldsMap.containsKey(removedLeadUnderscore)) && (leadfieldMap[cnt]!='RecordTypeId') && (leadfieldMap[cnt] !='Name'))
                {           
                    LeadOpptyMap.put(OpptyFieldsMap.get(removedLeadUnderscore),leadfieldMap[cnt]);
                }
                
            //End compare

        }            
        /*merge option 1*/        
      string updateValue;
      if(option=='option1')
      {
            System.debug('inside option1 in line 171 777777777777777777777');
            for(String s:LeadAccountMap.KeySet())
            {   
                if(account.get(s)==null && lead.get(LeadAccountMap.get(s))!=null)
                {    
                    account.put(s,lead.get(LeadAccountMap.get(s)));            
                }
            }
            
         List<task>  tsk = [Select id, whatId,whoId from Task where whoId =: ApexPages.currentPage().getParameters().get('leadID') ];
          system.debug('##################### If any tasks were there with the lead OPTION YES  ' + tsk.size());   
           if(tsk.size()>0)
             {
                for(task t : tsk )
                   {
                     t.whatid = account.Id ;
                     t.whoId = null ;
                     tskToUpdate.add(t);
                   }
                   
              }
              
         List<event>  evnt = [Select id, whatId,whoId from EVENT where whoId =: ApexPages.currentPage().getParameters().get('leadID') ];
          system.debug('##################### If any tasks were there with the lead OPTION YES  ' + evnt.size());   
           if(evnt.size()>0)
             {
                for(event et : evnt)
                   {
                     et.whatid = account.Id ;
                     et.whoId = null ;
                     eventToUpdate.add(et);
                   }
                   
              }              
                     
               
     /*merge option 2*/        
    /* if(option=='option2')
    {
        for(String s:LeadAccountMap.KeySet())
        {
            if(lead.get(LeadAccountMap.get(s))!=null)
            {
                account.put(s,lead.get(LeadAccountMap.get(s)));        
            }
        }
    } */
    try
    {
        Database.SaveResult SR = database.update(account);
        List<Database.SaveResult> SRR = database.update(tskToUpdate); 
        List<Database.SaveResult> SRRes = database.update(eventToUpdate);                     
    }
    catch(DMLException e){
   ApexPages.addMessage(accErr);
    }
   }
        /*option 3*/
        /*create an opportunity*/        
        //if(option=='option3')
        if(isOppty==true && option=='option1')
        {
              System.debug('in line 233 888888888888888888888888888');
            Opportunity opportunity=new Opportunity();
            if(lead.lastName!=null)
            {
                opportunity.name=lead.lastName;
            }
            Account ac ;
            if(account.ID != null)
            {
                ac = [ Select Id,   CEL_Assigned__c, CEL_Assigned_Date__c, CEL_Assigned_Legacy__c from Account where id =:account.id];
            }
             opportunity.accountId=account.Id;
            opportunity.OwnerId=lead.OwnerId;        
            opportunity.stagename='Started';
            if(ac != null)
            {
            opportunity.CEL_Assigned__c = ac.CEL_Assigned__c;
            opportunity.CEL_Assigned_Date__c = ac.CEL_Assigned_Date__c;
            opportunity.CEL_Assigned_Legacy__c = ac.CEL_Assigned_Legacy__c;
            }
            opportunity.LeadConversionInProgress__c = true;
            opportunity.closedate=date.parse('12/12/2012');
            boolean isSuccess = false;
            for(String s:LeadOpptyMap.KeySet())
            {                         
                if(lead.get(LeadOpptyMap.get(s))!=null)
                {
                    opportunity.put(s,lead.get(LeadOpptyMap.get(s)));
                }
            }
            try{
                insert opportunity;
                isSuccess = true;
                }
            catch(DMLException e){
        
                ApexPages.addMessage(oppErr);
            }
            finally
            {
                if(isSuccess )
                {
                Opportunity op = new Opportunity(Id = opportunity.Id, LeadConversionInProgress__c= false);
                update op;
                }
            }
        }
        
        try{
            System.debug('Converting lead at line 282 777777777777777777777');
            database.LeadConvert convertLead= new database.LeadConvert();
            convertLead.setLeadId(lead.id);
            LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true LIMIT 1];
            convertLead.setConvertedStatus(convertStatus.MasterLabel);
            Database.LeadConvertResult convertedResult= Database.convertLead(convertLead);
            Lead ConvertedLead = [SELECT Name, Id, IsConverted, ConvertedDate, ConvertedAccountId, ConvertedContactId, ConvertedOpportunityId FROM Lead WHERE IsConverted = True AND Id =:Lead.ID limit 1 ];
            String ConvertedAccountId = ConvertedLead.ConvertedAccountId;
            String ConvertedOpportunityId = ConvertedLead.ConvertedOpportunityId;
            String ConvertedContactId = ConvertedLead.ConvertedContactId;
            List<Opportunity> opp=[select id from Opportunity where id=:ConvertedOpportunityId];
            List<Account> a=[select id from ACCOUNT where id=:ConvertedAccountId];
           if(option != 'option2')
            {
               if(opp.size()>0){
               delete opp;
               }
                             
                  if(a.size()>0){
                    delete a;
                   }
                system.debug('##################### Line 303 ');   
            } 
           if(option == 'option2')
            {
            
                System.debug('inside option2 in line 308 777777777777777777777');
             List<task>  tsks = [Select id, whatId,whoId from Task where whoId =: ApexPages.currentPage().getParameters().get('leadID') ]; 
             system.debug('##################### If any tasks were there with the lead  ' + tsks.size());   
            if(tsks.size()>0)
             {
                for(task t : tsks )
                   {
                     t.whatid = a[0].Id ;
                     t.whoId = null ;
                     tskToUpdate.add(t);
                   }
                   
              }
              
               List<event>  evnts = [Select id, whatId,whoId from EVENT where whoId =: ApexPages.currentPage().getParameters().get('leadID') ];
               system.debug('##################### If any tasks were there with the lead OPTION NO  ' + evnts.size());   
            if(evnts.size()>0)
             {
                for(event et : evnts)
                   {
                     et.whatid = account.Id ;
                     et.whoId = null ;
                     eventToUpdate.add(et);
                   }
                   
              }
             List<Database.SaveResult> SRR = database.update(tskToUpdate); 
             List<Database.SaveResult> SRRe = database.update(eventToUpdate);  
             PageReference pr=new PageReference('/'+a[0].Id);
             return pr;   

            } 
                     
        }
        catch(Exception e){
        ApexPages.addMessage(leadErr);
        }
       AccountUpdate(led,act,false,option);
        
         PageReference pr=new PageReference('/'+account.Id);
         return pr;
                 
         
    }
    
    
    public void  AccountUpdate(lead led, account act,boolean mode,string options)
    {  
        act.LeadConversionInProgress__c=mode;
        if(mode==true)
        {
           if(option=='option1')
            {
                if(act.PersonMailingStreet==null)        
                    act.PersonMailingStreet = led.Street;
            
                if(act.PersonMailingState==null)
                    act.PersonMailingState= led.State;
                    
                if(act.PersonMailingCity==null)        
                    act.PersonMailingCity = led.City;
                    
                if(act.PersonMailingPostalCode==null)
                    act.PersonMailingPostalCode = led.PostalCode;
            
                if(act.PersonMailingCountry==null)
                    act.PersonMailingCountry = led.Country;
                //if(act.Personal_Email__pc==null)
                  //  act.Personal_Email__pc=led.Personal_Email__c;

            }   
         }
     update act;
    }
    
    public static List<String> getoDescribe(string selectedObject)
    {
        List<String> listObjectFields;
        listObjectFields =  new List<String>();
        Map<String , Schema.SObjectType> globalDescription = Schema.getGlobalDescribe();        
        Schema.sObjectType sObjType = globalDescription.get(selectedObject);        
        sObject sObjectToBind = sObjType.newSObject();
        Schema.DescribeSObjectResult r1 = sObjType.getDescribe();        
        Map<String , Schema.SObjectField> mapFieldList = r1.fields.getMap();
        for(Schema.SObjectField field : mapFieldList.values())
        {
                Schema.DescribeFieldResult fieldResult = field.getDescribe();
                //leave out the read only fields
                if((fieldResult.isUpdateable())&&(fieldResult.isCalculated()==false))
                {
                    listObjectFields.add(fieldResult.getName()); 
                }
        }
        return  (listObjectFields);              
    }
}